﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security.Cryptography;
using WBGModel;

namespace WBGDal
{
    public class clsDalCriptografia
    {
        // Vetor de bytes utilizados para a criptografia (Chave Externa)

        private static byte[] bIV = { 0x50, 0x08, 0xF1, 0xDD, 0xDE, 0x3C, 0xF2, 0x18, 0x44, 0x74, 0x19, 0x2C, 0x53, 0x49, 0xAB, 0xBC };

        // Representação de valor em base 64 (Chave Interna)
        // O Valor representa a transformação para base64 de 
        // um conjunto de 32 caracteres (8 * 32 = 256bits)
        // A chave é: "Criptografias com Rijndael / AES"

        private const string cryptoKey = "Q3JpcHRvZ3JhZmlhcyBjb20gUmluamRhZWwgLyBBRVM=";

        // Método de criptografia de valor
        // valor a ser criptografado
        // valor criptografado
        public static string Encrypt(string text)
        {
            try
            {
                // Se a string não está vazia, executa a criptografia
                if (!string.IsNullOrEmpty(text))
                {
                    // Cria instancias de vetores de bytes com as chaves
                    byte[] bKey = Convert.FromBase64String(cryptoKey);
                    byte[] bText = new UTF8Encoding().GetBytes(text);

                    // Instancia a classe de criptografia JPBAS
                    Rijndael rindael = new RijndaelManaged();

                    // Define o tamanho da chave "256 = 8 * 32"
                    // Lembre-se: chaves possíveis:
                    // 128 (16 caracteres), 192 (24 caracteres) e 256 (32 caracteres)

                    MemoryStream mStream = new MemoryStream();
                    // Instancia o encriptador
                    CryptoStream encryptor = new CryptoStream(mStream, rindael.CreateEncryptor(bKey, bIV), CryptoStreamMode.Write);

                    // Faz a escrita dos dados criptografados no espaço de memória
                    encryptor.Write(bText, 0, bText.Length);
                    // Despeja toda a memória
                    encryptor.FlushFinalBlock();
                    // Pega o vetor de bytes da memória e gera a string criptografada

                    return Convert.ToBase64String(mStream.ToArray());
                }
                else
                {
                    // Se a string for vazia retorna nulo
                    return null;
                }
            }
            catch (Exception ex)
            {
                // Se algum erro ocorrer, dispara a exceção
                throw new ApplicationException("Erro ao criptografar", ex);
            }
        }

        // Pega um valor previamente criptografado e retorna o valor inicial
        // texto criptografado
        // valor descriptografado
        public static string Descrypt(string text)
        {
            try
            {
                // Se a string não está vazia, executa a criptografia
                if (!string.IsNullOrEmpty(text))
                {
                    // Cria instancias de vetores de bytes com as chaves
                    byte[] bKey = Convert.FromBase64String(cryptoKey);
                    byte[] bText = Convert.FromBase64String(text);

                    // Instancia a classe de criptografia Rijndael
                    Rijndael rijndael = new RijndaelManaged();

                    // Define o tamanho da chave "256 = 8 * 32"
                    // Lembre-se: chaves possíveis;
                    // 128 (16 caracteres), 192 (24 caracteres) e 256 (32 caracteres)

                    rijndael.KeySize = 256;

                    // Cria o espaço de memória para guardar o valor DEScriptografado:

                    MemoryStream mStream = new MemoryStream();

                    // Instancia o Descriptador
                    CryptoStream decryptor = new CryptoStream(mStream, rijndael.CreateDecryptor(bKey, bIV), CryptoStreamMode.Write);

                    // Faz a escrita dos dados criptografados no espaço de memória
                    decryptor.Write(bText, 0, bText.Length);
                    // Despeja toda a memória
                    decryptor.FlushFinalBlock();
                    // Instancia a classe de codificação para a string venha de forma correta

                    UTF8Encoding utf8 = new UTF8Encoding();
                    // Com o vetor de bytes da memória, gera a string descriptografada em UTF8

                    return utf8.GetString(mStream.ToArray());
                }
                else
                {
                    // Se a string for vazia retorna nulo
                    return null;
                }
            }
            catch (Exception ex)
            {
                // Se algum erro ocorrer, diapara a exceção
                throw new ApplicationException("Erro ao Descriptografar", ex);
            }
        }

    }
}